<?php

CRequire('CObject');

define ('kCURLParseError', 'kCURLParseError');
define ('kCURLSchemeMissing', 'kCURLSchemeMissing');

class CURL extends CObject {
	function SchemeMissing($reason) {
		return new CError(kCURLSchemeMissing,
			'The scheme of this URL is missing', $reason);
	}
	
	function ParseError($reason) {
		return new CError(kCURLErrorDomain, kCURLParseError,
			'The URL string given could not be parsed', $self, $reason);
	}
	
	var $Scheme;
	var $Host;
	var $Port;
	var $User;
	var $Pass;
	var $Path;
	var $Query;
	var $Fragment;
	
	function &MakeCopy() {
		$e = null;
		$c = &new CURL(null, $e);
		
		$c->Scheme = $this->Scheme;
		$c->Host = $this->Host;
		$c->Port = $this->Port;
		$c->User = $this->User;
		$c->Pass = $this->Pass;
		$c->Path = $this->Path;
		$c->Query = $this->Query;
		$c->Fragment = $this->Fragment;
		
		return $c;
	}
	
	function Init($string, &$error) {
		if (is_null($string))
			return;
		
		$parts = @parse_url($string);
		if (!is_array($parts)) {
			$error = CURL::ParseError(null);
			return;
		}
		
		$this->Scheme = @$parts['scheme'];
		$this->Host = @$parts['host'];
		$this->Port = @$parts['port'];
		$this->User = @$parts['user'];
		$this->Pass = @$parts['pass'];
		$this->Path = @$parts['path'];
		$q = @$parts['query'];
		if (!is_null($q))
			parse_str($q, $this->Query);
		
		$this->Fragment = @$parts['fragment'];
	}
	
	function _ToQueryString($arr) {
		$s = ''; $and = false;
		foreach ($arr as $k => $v) {
			if ($and) $s .= '&';
			$s .= urlencode($k) . '=' . urlencode($v);
			$and = true;
		}
		
		return $s;
	}
	
	function __toString() { return $this->AsString(); }
	
	function AsString() {
		if (is_null($this->Scheme))
			return CURL::SchemeMissing(null);
		
		$s = $this->Scheme . ':';
		
		if (!is_null($this->Host)) {
			$s .= '//';
			if (!is_null($this->User)) {
				$s .= $this->User;
				if (!is_null($this->Pass))
					$s .= ':' . $this->Pass;
				$s .= '@';
			}
			
			$s .= $this->Host;
			if (!is_null($this->Port))
				$s .= ':' . $this->Port;
		}
		
		$s .= $this->Path;
		
		if (!is_null($this->Query)) {
			$q = $this->Query;
			if (is_array($q))
				$q = CURL::_ToQueryString($q);
			
			$s .= '?' . $q;
		}
		
		if (!is_null($this->Fragment))
			$s .= '#' . $this->Fragment;
		
		return $s;
	}
	
	function &FromString($str, $triggerOnError = null) {
		$error = null;
		$c = &new CURL($str, $error);
		if ($triggerOnError)
			if ($error) $error->Raise();
		
		if (is_null($error)) return $c;
		return $error;
	}
	
	function SelfURLString() {
		$s = CURL::_InitialPartOfURLString() . $_SERVER['PHP_SELF'];
		if (!is_null($_SERVER['QUERY_STRING']))
			$s .= '?' . $_SERVER['QUERY_STRING'];
		return $s;
	}
	
	function &SelfURL() {
		if (!isset($GLOBALS['_CURLSelf']))
			$GLOBALS['_CURLSelf'] = &CURL::FromString(CURL::SelfURLString());
		
		return $GLOBALS['_CURLSelf'];
	}
	
	function _InitialPartOfURLString() {
		global $_CURLInitialPart;
		if (!isset($_CURLInitialPart)) {
			$protocol = (substr($_SERVER['SERVER_PROTOCOL'], 0, 5) == 'HTTP/')? 'http' : 'https';
			$_CURLInitialPart = "$protocol://" . $_SERVER['HTTP_HOST'];
		}
	
		return $_CURLInitialPart;
	}
}

?>